---
title: Migrating from Mypy

description: How to switch your type checker configuration from Mypy to Pyrefly
---

## Running Pyrefly

Like mypy, pyrefly can be given a list of files to check:

```sh
$ pyrefly check file1.py file2.py
```

The easiest way to run pyrefly on all files in a project is to run it from the project root:

```sh
$ cd your/project
$ pyrefly check
```

Pyrefly is designed to have sensible defaults, and you may not need to configure it at all.
However, projects with existing mypy configs may want to configure pyrefly to suit their own needs.

## Mypy Config Migration

To make it as easy as possible to get started with pyrefly, we've provided a script for automatically migrating a mypy config to pyrefly.

```sh
$ pyrefly init path/to/your/project
```

This will search for an existing `mypy.ini` or `pyproject.toml` with a `tool.mypy` section, and then transform it into a `pyrefly.toml` (or `[tool.pyrefly]` section) while preserving as many options as possible. See `init --help` for more options.

We do recommend checking the resulting config for errors. While there is some overlap between mypy's config options and pyrefly's config options, it's not always possible to cleanly translate one config option to another.

If you'd rather start fresh with a hand-written config, please see the [pyrefly configuration docs](configuration.mdx).
If you run into any issues with config migration, please [let us know](https://github.com/facebook/pyrefly/issues)!

### Config options

The following config options make Pyrefly behave more like Mypy:

```toml
# By default, mypy does not check unannotated function bodies. The following flag will configure Pyrefly to match mypy's behavior:
untyped_def_behavior = "skip-and-infer-return-any"
```
```toml
# If mypy is configured with `--check-untyped-defs` or `--strict` it will check function bodies where the function signature is unannotated.
# The following flag will enable this behavior:
untyped_def_behavior = "check-and-infer-return-any"
```

```toml
# Direct Pyrefly to respect `# mypy: ignore` and `# mypy: ignore-errors` comments
permissive-ignores = true
```

### Config Migration Details

`files`, `modules`, and `packages` are combined into `project_includes`. This should work exactly the same for `files` and `packages`. Mypy doesn't recurse into `modules`, but pyrefly will.

Pyrefly makes an effort to transform the `exclude` regex into a list of filepath globs for `project_excludes`. This should excel on simple regexes, such as `some/file.py|exclude_dir/`, which becomes `["**/some/file.py", "**/exclude_dir/"]`.

The `ignore_missing_imports` per-module config option is turned into a list of modules. For example:

```ini
[mypy-some.*.module]
ignore_missing_imports = True
```

Becomes:

```toml
replace_imports_with_any = ["some.*.module"]
```

Mypy's `follow_imports = "skip"` is handled the same way.

Pyrefly does support mypy's [module name pattern syntax](https://mypy.readthedocs.io/en/stable/config_file.html#config-file-format): see [Module Globbing](configuration.mdx#module-globbing) in the configuration docs.

Mypy's `follow_untyped_imports` option is allowed to be global or per-module. The pyrefly equivalent, `use_untyped_imports`, is only global. This setting defaults to `true` unless
the `follow_untyped_imports` is disabled in the `[mypy]` section of the migrated config.

### Mypy Error Codes and Pyrefly Error Kinds

Pyrefly maps Mypy's [error codes](https://mypy.readthedocs.io/en/stable/error_code_list.html) to equivalent pyrefly [error kinds](error-kinds.mdx).
While not every error code has an equivalent error kind, we make an effort to ensure that pyrefly suppresses the same errors that mypy does.

This may lead to overly broad error suppressions, and you may want to consider removing some error kinds from the disable list.
You can also use a [SubConfig](configuration.mdx#sub_config) to selectively silence errors in specific files,
or see [Silencing Errors](#silencing-errors) for how to suppress errors at the source.

See [Error Kind Mapping](#error-kind-mapping) for a table showing the relationship between type check diagnostic settings and error kinds.

### Per-Module configs

Mypy's per-module configs let you change a wide range of configuration options for modules matching a module wildcard.
Pyrefly's [SubConfigs](configuration.mdx#sub_config) are a similar mechanism that let you configure pyrefly's behavior for files matching a filepath glob.
However, they support significantly fewer options, and only `disable_error_code` and `enable_error_code` will be migrated over to the pyrefly config.

## Silencing Errors

Like mypy, pyrefly has ways to silence specific error codes. Full details can be found in the [Error Suppression docs](error-suppressions.mdx)

To silence an error on a specific line, add a disable comment above that line. You can either suppress all errors on that line:

```
# pyrefly: ignore
x: str = 1
```

Or target a specific error type:

```
# pyrefly: ignore[bad-assignment]
x: str = 1
```

To suppress all instances of an error, disable that error in the config:

```
[errors]
missing-import = false
```

This is equivalent to mypy's `disable_error_code`, though of course the [error codes](error-kinds.mdx) are different!

### Error Kind Mapping


This table shows the mapping between mypy's [error codes](https://mypy.readthedocs.io/en/stable/error_code_list.html) and pyrefly's [error kinds](error-kinds.mdx).

This table will be expanded as more diagnostics are supported.

| Mypy | Pyrefly |
| ------- | ------- |
| attr-defined | missing-attribute |
| union-attr | missing-attribute |
